/* 20250404
 * 操作人员请注意，该文件为chsf.c中的zzhi字库（GB2312）转换为UTF32储存
 * 运行该程序会覆盖已有的chsf32.c文件，望悉知
 *
 * 在转换过程中已知位置380：0xA3FF处的字符是无效的并以0填充了。
 */

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <iconv.h>
#include <errno.h>
#include <wchar.h>
#include <locale.h>

// 测试数据（GB2312 编码的 "你好"）
//uint8_t zzhi[] = {0xC4, 0xE3, 0xBA, 0xC3}; // "你好" 的 GB2312 编码
//int zzhinumber = 4; // 字节数（2 个汉字 × 2 字节）
extern uint8_t zzhi[];
extern int zzhinumber;

int main() {
    // 设置 locale 以支持宽字符转换
    setlocale(LC_ALL, "en_US.UTF-8");

    if (zzhinumber % 2 != 0) {
        fprintf(stderr, "错误：zzhi 长度必须是偶数（GB2312 每个字符 2 字节）\n");
        return 1;
    }
    
    FILE *f = fopen("./chsf32.c", "w");
    if (!f) {
    	perror("fopen");
    	exit(1);
    }
    
    fprintf(f, "#include <stdint.h>\n");
    fprintf(f, "uint8_t zzhi32[] = {");

    int i;
    for (i = 0; i < zzhinumber; i += 2) {
    	//wprintf(L"%d: %d\n", zzhinumber, i + 1);
        uint8_t high_byte = zzhi[i];
        uint8_t low_byte = zzhi[i + 1];
        char gb2312[3] = {high_byte, low_byte, '\0'};

        // Step 1: GB2312 → UTF-8
        size_t in_len = 2;
        size_t out_len = 4;
        char *out_buf = malloc(out_len + 1);
        if (!out_buf) {
            perror("malloc failed");
            return 1;
        }

        iconv_t cd = iconv_open("UTF-8", "GB18030");
        if (cd == (iconv_t)-1) {
            perror("iconv_open failed");
            free(out_buf);
            return 1;
        }

        char *in_ptr = gb2312;
        char *out_ptr = out_buf;
        size_t in_bytesleft = in_len;
        size_t out_bytesleft = out_len;

        size_t ret = iconv(cd, &in_ptr, &in_bytesleft, &out_ptr, &out_bytesleft);
        if (ret == (size_t)-1) {
            fprintf(stderr, "转换失败（位置 %d: 0x%02X%02X）: %s\n",
                    i, (unsigned char)gb2312[0], (unsigned char)gb2312[1],
                    strerror(errno));
//            iconv_close(cd);
//            free(out_buf);
//            continue;
	    *out_buf = 0;
        }

        *out_ptr = '\0';
        iconv_close(cd);

        //printf("原始字节: 0x%02X%02X → UTF-8: %s\n",
        //       (unsigned char)gb2312[0], (unsigned char)gb2312[1], out_buf);

        // Step 2: UTF-8 → wchar_t
        size_t wchar_size = mbstowcs(NULL, out_buf, 0) + 1; // 计算需要的宽字符数
        if (wchar_size == (size_t)-1) {
            fprintf(stderr, "无法计算宽字符长度\n");
            free(out_buf);
            continue;
        }

        wchar_t *wchar_buf = malloc(wchar_size * sizeof(wchar_t));
        if (!wchar_buf) {
            perror("malloc failed");
            free(out_buf);
            continue;
        }

        if (mbstowcs(wchar_buf, out_buf, wchar_size) == (size_t)-1) {
            fprintf(stderr, "UTF-8 转 wchar_t 失败\n");
            free(out_buf);
            free(wchar_buf);
            continue;
        }

        // 打印宽字符结果
        wprintf(L"原始字节: 0x%02X%02X(%d) → 宽字符UTF8: %ls (%d)\n", (unsigned char)gb2312[0], (unsigned char)gb2312[1], (high_byte << 8) | low_byte, wchar_buf, *wchar_buf);

	uint8_t *k = (uint8_t*)wchar_buf;
	fprintf(f, "%d,%d,%d,%d,", k[0], k[1], k[2], k[3]);

        free(out_buf);
        free(wchar_buf);
    }
 
    fprintf(f, "};\nint zzhinumber32 = sizeof(zzhi32) / 4;\n");   
    fclose(f);

    return 0;
}
